﻿/*
创建日期:	2017/5/11 23:54:20     
作	  者:	张存
邮 	  箱:	zhangcunliang@126.com
创建时间:	
Copyright (c)    ZhCun.cn
描	述：
记	录：
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Text;
using ASmile.ORM.ADO;
using ASmile.ORM.Entitys;

namespace ASmile.ORM.Cores
{
    public class ProcResultBase : BaseResult
    {
        protected internal ProcResultBase(IDBHelper dbHelper, string procName, Dictionary<string, object> args = null)
        {
            DbHelper = dbHelper;
            ProcName = procName;
            OtherArgs = args;
        }

        protected string ProcName { get; }

        public DbParameter[] ProcParams { get; protected set; }
        /// <summary>
        /// ProcModel 之外的其它输入参数
        /// </summary>
        public Dictionary<string, object> OtherArgs { get; }

        protected IDBHelper DbHelper { get; }

        protected virtual void SetProcParams()
        {
            if (ProcParams != null) return;
            ProcParams = DbHelper.ConvertDbParameter(OtherArgs);
        }

        public override string SqlContent
        {
            get
            {
                if (_SqlContent == null)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendFormat("{0}\r\n", ProcName);
                    if (ProcParams != null)
                    {
                        foreach (var param in ProcParams)
                        {
                            sb.AppendFormat("Param（{2}）：{0}，Value：{1}\r\n", param.ParameterName, param.Value, param.Direction);
                        }
                    }
                    _SqlContent = sb.ToString();
                }
                return _SqlContent;
            }
        }
        /// <summary>
        /// 执行存储过程返回所影响行数
        /// </summary>
        public virtual int ExecProc()
        {
            SetProcParams();
            RowCount = DbHelper.ExecNonQuery(ProcName, CommandType.StoredProcedure, ProcParams);
            SetIntervalResult();
            return RowCount;
        }
        /// <summary>
        /// 执行存储过程返回DataTalbe
        /// </summary>
        public virtual DataTable ToDataTable()
        {
            SetProcParams();
            var r = DbHelper.GetDataTable(ProcName, CommandType.StoredProcedure, ProcParams);
            SetIntervalResult();
            return r;
        }
        /// <summary>
        /// 执行存储过程返回 DataSet
        /// </summary>
        public virtual DataSet ToDataSet()
        {
            SetProcParams();
            var r = DbHelper.GetDataSet(ProcName, CommandType.StoredProcedure, ProcParams);
            SetIntervalResult();
            return r;
        }
        /// <summary>
        /// 执行存储过程返回List
        /// </summary>
        protected virtual List<TEntity> ToList<TEntity>(bool isFirst) where TEntity : class, new()
        {
            SetProcParams();
            var dbReader = DbHelper.GetDataReader(ProcName, CommandType.StoredProcedure, ProcParams);
            var rList = Reflection.GetListByDataReader<TEntity>(dbReader, isFirst);
            SetIntervalResult();
            return rList;
        }
        /// <summary>
        /// 执行存储过程返回List
        /// </summary>
        public List<TEntity> ToList<TEntity>() where TEntity : class, new()
        {
            return ToList<TEntity>(false);
        }
        /// <summary>
        /// 执行存储过程返回首行
        /// </summary>
        public TEntity ToEntity<TEntity>() where TEntity : class, new()
        {
            List<TEntity> rList = ToList<TEntity>(true);
            if (rList != null && rList.Count > 0)
            {
                return rList[0];
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 返回首行首列
        /// </summary>
        public object ToObject()
        {
            SetProcParams();

            object obj = DbHelper.GetScalar(ProcName, CommandType.StoredProcedure, ProcParams);
            RowCount = (obj == null || obj is DBNull) ? 0 : 1;
            SetIntervalResult();

            return obj;
        }
        /// <summary>
        /// 返回首行首列
        /// </summary>
        public T ToObject<T>()
        {
            object obj = ToObject();
            if (obj == null || obj is DBNull)
            {
                return default;
            }
            object result = Convert.ChangeType(obj, typeof(T));
            return (T)result;
        }

        protected internal override bool SetTiming(DateTime startTime, Action<BaseResult> argTimingEndHandle)
        {
            return SetTimingHandle(startTime, argTimingEndHandle);
        }
    }

    public class ProcResult : ProcResultBase
    {
        protected internal ProcResult(IDBHelper dbHelper, ProcEntityBase procModel, Dictionary<string, object> otherArgs = null)
            : base(dbHelper, procModel.GetProcedureName(), otherArgs)
        {
            ProcModel = procModel;
        }
        /// <summary>
        /// 存储过程参数对象
        /// </summary>
        ProcEntityBase ProcModel { get; }

        protected override void SetProcParams()
        {
            if (ProcParams != null) return;
            ProcParams = ProcModel.GetProcParamObj(DbHelper.CreateDbParameter, OtherArgs);
        }
        /// <summary>
        /// 执行存储过程返回所影响行数
        /// </summary>
        public override int ExecProc()
        {
            SetProcParams();
            RowCount = DbHelper.ExecNonQuery(ProcName, CommandType.StoredProcedure, ProcParams);
            ProcModel.SetOutParamValue(ProcParams);
            SetIntervalResult();
            return RowCount;
        }
        /// <summary>
        /// 执行存储过程返回DataTalbe
        /// </summary>
        public override DataTable ToDataTable()
        {
            SetProcParams();
            var r = DbHelper.GetDataTable(ProcName, CommandType.StoredProcedure, ProcParams);
            ProcModel.SetOutParamValue(ProcParams);
            SetIntervalResult();
            return r;
        }
        /// <summary>
        /// 执行存储过程返回 DataSet
        /// </summary>
        public override DataSet ToDataSet()
        {
            SetProcParams();
            var r = DbHelper.GetDataSet(ProcName, CommandType.StoredProcedure, ProcParams);
            ProcModel.SetOutParamValue(ProcParams);
            SetIntervalResult();
            return r;
        }
        /// <summary>
        /// 执行存储过程返回List
        /// </summary>
        protected override List<TEntity> ToList<TEntity>(bool isFirst)
        {
            SetProcParams();
            var dbReader = DbHelper.GetDataReader(ProcName, CommandType.StoredProcedure, ProcParams);
            var rList = Reflection.GetListByDataReader<TEntity>(dbReader, isFirst);
            ProcModel.SetOutParamValue(ProcParams);
            SetIntervalResult();
            return rList;
        }
    }
}